package cn.hd01.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import cn.hd01.repository.COrderPaymentRepository;
import cn.hd01.repository.entity.COrderPayment;
import cn.hd01.repository.entity.PayTypeReport;
import cn.hd01.service.COrderPaymentService;

@Service
public class COrderServicePaymentImpl extends BaseServiceImpl<COrderPayment, Integer> implements COrderPaymentService {

	private COrderPaymentRepository repository;
	
	@Autowired
	private EntityManager em;
	
	@Autowired
	public COrderServicePaymentImpl(COrderPaymentRepository repository) {
		super(repository);
		this.repository = repository;
	}

	@Override
	public Page<COrderPayment> findAll(final COrderPayment payment, Pageable pageable) {
		if (payment == null) {
			return repository.findAll(pageable);
		}

		return repository.findAll(Specifications.where(new Specification<COrderPayment>() {
			@Override
			public Predicate toPredicate(Root<COrderPayment> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				List<Predicate> predicates = new ArrayList<Predicate>();
				
				if(payment.getOrderId() != null){
					predicates.add(cb.equal(r.get("orderId").as(Integer.class), payment.getOrderId()));
				}
				
				if(StringUtils.hasText(payment.getPayType()) && !"-1".equals(payment.getPayType())){
					predicates.add(cb.equal(r.get("payType").as(String.class), payment.getPayType()));
				}
				
				if(StringUtils.hasText(payment.getPayee()) && !"-1".equals(payment.getPayee())){
					predicates.add(cb.equal(r.get("payee").as(String.class), payment.getPayee()));
				}
				
				if (StringUtils.hasText(payment.getPayTimeBeginTime())) {
					predicates.add(cb.greaterThanOrEqualTo(r.get("payTime").as(String.class), payment.getPayTimeBeginTime()));
				}
				
				if (StringUtils.hasText(payment.getPayTimeEndTime())) {
					predicates.add(cb.lessThanOrEqualTo(r.get("payTime").as(String.class), payment.getPayTimeEndTime()));
				}
				return cb.and(predicates.toArray(new Predicate[] {}));
			}
		}), pageable);
	}

	@Override
	public List<COrderPayment> findByOrderId(Integer OrderId) {
		return repository.findByOrderIdOrderByPayTimeDesc(OrderId);
	}

	@Override
	public BigDecimal[] findAllAmount(Integer orderId) {
		List<Object[]> list = repository.findAllAmount(orderId);
		BigDecimal[] amount = new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO};
		if(!CollectionUtils.isEmpty(list)){
			Object[] amountArr = list.get(0);
			amount[0] = (BigDecimal) amountArr[0];
			amount[1] = (BigDecimal) amountArr[1];
			amount[2] = (BigDecimal) amountArr[2];
			amount[3] = (BigDecimal) amountArr[3];
		}
		return amount;
	}

	@Override
	public List<Object[]> findRebate() {
		return repository.findRebate();
	}

	@Override
	public int deleteByOrderId(Integer orderId) {
		return repository.deleteByOrderId(orderId);
	}

	@Override
	public Page<PayTypeReport> findPayTypeReport(Pageable pageable, PayTypeReport report) {
		StringBuffer sql = new StringBuffer("SELECT pay_type, SUM(amount) amount, SUM(fee_amount) fee_amount, SUM(IFNULL(distributor_rebate, 0) + IFNULL(recomm_distributor_rebate, 0)) k_value FROM  c_order_payment WHERE 1 = 1 ");
		
		if(StringUtils.hasText(report.getBeginDate())){
			sql.append(" and create_time >= '").append(report.getBeginDate()).append("'");
		}
		
		if(StringUtils.hasText(report.getEndDate())){
			sql.append(" and create_time <= '").append(report.getEndDate()).append("'");
		}
		
		if(!StringUtils.hasText(report.getBeginDate()) && !StringUtils.hasText(report.getEndDate())){
			sql.append(" and DATE_FORMAT(create_time, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') ");
		}
		
		sql.append(" GROUP BY pay_type");
		
		Query query = em.createNativeQuery(sql.toString(), PayTypeReport.class);
		List<PayTypeReport> objectList = query.getResultList();

		PayTypeReport summary = new PayTypeReport("收款总额", BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
		if(!CollectionUtils.isEmpty(objectList)){
			for(PayTypeReport result : objectList){
				summary.setAmount(summary.getAmount().add(result.getAmount()));
				summary.setFeeAmount(summary.getFeeAmount().add(result.getFeeAmount()));
				summary.setkValue(summary.getkValue().add(result.getkValue()));
			}
		}
		objectList.add(0, summary);
		return new PageImpl<PayTypeReport>(objectList, pageable, objectList.size());
		
	}

}
